<template>
  <div class="image-container custom-border">
      <header class="header custom-border">
         <el-row>
             <!-- <el-upload></el-upload> -->
            <el-button   type="primary">上传录音文件</el-button>
            <el-button  @click="selectLocalFile" type="primary" >播放本地录音文件</el-button>
            <audio class="audio" ref="audio" controls autoplay></audio>
            <span> &nbsp;&nbsp;{{audioName}}</span>

         </el-row>
        <el-button circle icon="el-icon-close" class="btn-close" @click="close" plain type="primary"></el-button>
      </header>
     
  </div>
</template>

<script>
// import config from "../../../../../video.config";
import WS2 from "@/library/js/ws2";
import { v4 as uuidv4 } from "uuid";
import RecordRTC from 'recordrtc'

export default {
  mixins: [WS2],
  name: "audio-button",
  components: {},
  props: {
    data: Object,
  },
  data: function () {
    return {
      clientId: null,
      animation: null,
      recorder: null,
      errMsg:{
        0: "正常",
        1: "推流服务端链接流媒体服务网络故障",
        2: "推流服务端连接摄像头网络故障",
        3: "并行推流路数超限",
        4: "推流服务端主机内存不足",
        5: "onvif探测失败",
        6: "onvif 获取能力失败",
        7: "onvif 云台控制失败",
        11: "流媒体服务未启动", //前端页面判断
        12: "请求的 rtmp 流不存在；原因推流服务未运行或 rtmp 地址错误", //前端页面判断
      },
      // config: config,
      audioContext: null,
      gainNode: null,
      audioName: null,
    };
  },

  mounted(){
    this.clientId = uuidv4();
    this.initAudioContext();
  },
  methods: {
    async registVideoClient() {
      let data = {
        type_no: 200,
        regist_name:  this.clientId,
        project_id: this.data.camera_info.project_id,
		client_type: 1,
      };
      this.sendData(data); //注册
    },
    async sendData(data){
        if(this.ws) this.ws.send(JSON.stringify(data));
    },
    openAudio(){
     
      this.createWS();
      this.ws.onopen = ()=>{ 
        this.registVideoClient();
      }
      this.ws.onmessage = ({ data }) => {
        data = JSON.parse(data);
        const code = data.error_no;
        if (code && code !== 5 && code !== 6 && code !== 7) {
          this.$message({
            type: "error",
            message: this.errMsg[data.error_no],
          });
        }
        switch(data.type_no){
          // 注册返回消息
          case 300: 
            if(data.regist_result)
            { 
              const cameraInfo = this.data.camera_info;
              let device = {
                  "type_no": 205,
                  "forward": true,
                  "project_id": this.data.project_id,
                  "from": this.clientId,   //前端ws id
                  "to": cameraInfo.push_id,
                  "camera_id": cameraInfo.uu_id,
                  "ip": cameraInfo.ip,
                  "user_name": cameraInfo.user_name,
                  "password": cameraInfo.password,
                  "camera_brand": 2,
                  "talk_ws_name": cameraInfo.uu_id + '@audio'
              }

              this.sendData(device);
            }
            else{
              this.closeAudio()
              this.$message({
                type: 'warning',
                message: data.message
              })
            }
            break;
          // 转发返回消息
          case 301:
            if(!data.forward_result){         
              this.closeAudio()
              this.$message({
                type: 'warning',
                message: data.message
              })
            }
            break
          // 接收 推流服务器 返回的消息
          case 101:
            if(data.error_no === 0)	// 对讲邀请成功
            {
              console.log("对讲邀请成功")
              this.initRecorder();
            }
            else
            {
              this.closeAudio()
              this.$message({
                type: 'warning',
                message: '对讲邀请失败'
              })
            }
            break;
          default:break;
        }
      }
      
    },
    closeAudio(){
      if(this.recorder) this.recorder.stopRecording();
      let data = {
        "type_no": 206,		//关闭
        "forward": true,
        "project_id": this.data.project_id,
        "from": this.clientId,   //前端ws id
        "to":  this.data.camera_info.push_id,
        "camera_id": this.data.camera_info.uu_id,
        "ip": this.data.camera_info.ip
      }
      this.sendData(data)
      this.ws.close();
      this.animation = null;
    },

    close(e){ 
      this.$parent.recordAudioVisible = false;
      this.$emit('close', e)
    },
    initAudioContext(){
        window.AudioContext = window.AudioContext || window.webkitAudioContext;
        this.audioContext = new AudioContext();
        this.gainNode = this.audioContext.createGain();
        this.gainNode.connect(this.audioContext.destination);
        this.gainNode.gain.value = 0; // don't play for self

    },

    selectLocalFile(){
        let input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.setAttribute('accept', 'audio/mp3');
        input.style.display = 'none';
        document.body.appendChild(input)
        input.click();

        // this.$refs.audio.onplay = function(e){
        //   console.log(e)
        // }

        const that = this;
        input.onchange = function(e){
            document.body.removeChild(input);
            let reader = new FileReader();
            reader.file = e.target.files[0];
            that.$refs.audio.src = URL.createObjectURL(reader.file)

            that.openAudio();
            that.audioName = reader.file.name;
            reader.onload = (function(e) {
              that.audioContext.decodeAudioData(e.target.result, that.createSoundSource);
            });
            reader.readAsArrayBuffer(reader.file);

        }
    },
    createSoundSource(buffer){
      var soundSource = this.audioContext.createBufferSource();
      soundSource.buffer = buffer;
      soundSource.start(0, 0 / 1000);
      soundSource.connect(this.gainNode);
      var destination = this.audioContext.createMediaStreamDestination();
      soundSource.connect(destination);
      // durtion=second*1000 (milliseconds)
      this.recordMp3Stream(destination.stream, buffer.duration * 1000);
    },
    recordMp3Stream(stream, duration) {
      if (!duration) duration = 3 * 1000;
      duration = parseInt(duration);

      let recordAudio = RecordRTC(stream, {
        recorderType: RecordRTC.StereoAudioRecorder,// MediaStreamRecorder,
        type: 'audio',
        mimeType: 'audio/wav',
        timeSlice: 100, // pass this parameter
        // getNativeBlob: true,

        //audioBitsPerSecond: 128000,
        bufferSize: 1024,
        numberOfAudioChannels: 1,
        desiredSampRate: 16000,

        ondataavailable: async (blob) =>{
          if(this.ws) this.ws.send(blob)
        }
      });

      // duration should be in milliseconds
      // RecordRTC will auto stop recording after provided duration
      recordAudio.setRecordingDuration(duration)
                  .onRecordingStopped(function(){
                    if(this.ws) this.ws.close();
                  });

      recordAudio.startRecording();
    }
  },
};
</script>

<style lang="scss"  scoped>
.image-container {
  display: flex;
  flex-direction: column;
  background:  linear-gradient(to bottom right, #041616, #2f5560);
  width: calc(100% - 18px);
  height: calc(100vh - 80px);
  box-sizing: border-box;
  position: absolute;
  left: 8px;
  top: 0;
  z-index: 10;
  .container{
    width: 100%;
    height: 100%;
  }
 .header{
     min-height: 60px;
     display: flex;
     align-items: center;
     padding: 0 15px;
     justify-content: space-between;
    .audio{
        height: 33px;
        margin-left: 10px;
        vertical-align: middle;
    }
  }


}
</style>
